/*
 * @Author: guandeshen 295570679@qq.com
 * @Date: 2024-05-08 23:51:45
 * @LastEditors: guandeshen 295570679@qq.com
 * @LastEditTime: 2024-07-15 09:45:50
 * @FilePath: /task-admin/src/directive/permission/index.ts
 * @Description:
 *
 * Copyright (c) 2024 by RSC, All Rights Reserved.
 */
import { useUserStoreHook } from "@/store/modules/user";
import { Directive, DirectiveBinding } from "vue";

/**
 * 菜单权限
 */
export const hasMenu: Directive = {
  mounted(el: HTMLElement, binding: DirectiveBinding) {
    // 「超级管理员」拥有所有的菜单权限
    const { roles, menus } = useUserStoreHook().user;
    if (roles.includes("ROOT")) {
      return true;
    }
    // 「其他角色」菜单权限校验
    const { value } = binding;
    if (value) {
      const requiredMenus = value; // DOM绑定需要的按钮权限标识
      const hasMenu = menus?.some((menu) => {
        return requiredMenus.includes(menu);
      });
      if (!hasMenu) {
        el.parentNode && el.parentNode.removeChild(el);
      }
    } else {
      throw new Error(
        "need perms! Like v-has-menu=\"['sys:user:list','sys:task:list']\""
      );
    }
  },
};
/**
 * 按钮权限
 */
export const hasPerm: Directive = {
  mounted(el: HTMLElement, binding: DirectiveBinding) {
    // 「超级管理员」拥有所有的按钮权限
    const { roles, perms } = useUserStoreHook().user;
    if (roles.includes("ROOT")) {
      return true;
    }
    // 「其他角色」按钮权限校验
    const { value } = binding;
    if (value) {
      const requiredPerms = value; // DOM绑定需要的按钮权限标识

      const hasPerm = perms?.some((perm) => {
        return requiredPerms.includes(perm);
      });

      if (!hasPerm) {
        el.parentNode && el.parentNode.removeChild(el);
      }
    } else {
      throw new Error(
        "need perms! Like v-has-perm=\"['sys:user:add','sys:user:edit']\""
      );
    }
  },
};

/**
 * 角色权限
 */
export const hasRole: Directive = {
  mounted(el: HTMLElement, binding: DirectiveBinding) {
    const { value } = binding;

    if (value) {
      const requiredRoles = value; // DOM绑定需要的角色编码
      const { roles } = useUserStoreHook().user;
      const hasRole = roles.some((perm) => {
        return requiredRoles.includes(perm);
      });

      if (!hasRole) {
        el.parentNode && el.parentNode.removeChild(el);
      }
    } else {
      throw new Error("need roles! Like v-has-role=\"['admin','test']\"");
    }
  },
};
